/*!
* @file BoundBox2.h
* @brief 二维包围盒
* @date 2024/9/13
*/
#pragma once

#include "Vector2D.h"

namespace data
{
/*!
* @brief 二维包围盒
*/
template<class float_type>
class BoundBox2
{
public:
    using traits_type = std::numeric_limits<float_type>;
    using vector_type = Vector2<float_type>;

    /*!
    * @brief 包围盒构造
    */
    BoundBox2() { MakeEmpty(); }
    BoundBox2(const BoundBox2&) = default;
    BoundBox2(BoundBox2&&) = default;
    BoundBox2(float_type x1, float_type y1, float_type x2, float_type y2) 
        : _minX(x1), _minY(y1), _maxX(x2), _maxY(y2) {}
    ~BoundBox2() = default;

    /*!
    * @brief 包围盒运算
    */
    BoundBox2& operator=(const BoundBox2&) = default;
    BoundBox2& operator=(BoundBox2&&) = default;
    bool operator==(const BoundBox2& bbox) const;

    void MakeEmpty();
    bool IsValid() const;

    float_type Width() const;
    float_type Height() const;
    vector_type Minimum() const;
    vector_type Maximum() const;
    vector_type Center() const;

    /*!
    * @brief 包围盒操作
    */
    void Add(const vector_type& v);
    bool Contains(const vector_type& v) const;
    bool Contains(const vector_type& v, float_type tol) const;
    void Add(const BoundBox2& bbox);
    bool Intersect(const BoundBox2& bbox) const;
    bool IsEqual(const BoundBox2& bbox, float_type tol) const;

    /*!
    * @brief 文本信息输出
    */
    friend std::ostream& operator<< (std::ostream& stream, const BoundBox2& b)
    {
        return stream << "{ minX: " << b._minX << ", _minY: " << b._minY << " maxX: " << b._maxX << ", _maxY: " << b._maxY << " }";
    }

private:
    /// 成员
    float_type _minX, _minY, _maxX, _maxY;
};

using BoundBox2f = BoundBox2<float>;
using BoundBox2d = BoundBox2<double>;
}  // namespace data

